/*
    This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
                       Matthias Butz <matze@odinms.de>
                       Jan Christian Meyer <vimes@odinms.de>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License version 3
    as published by the Free Software Foundation. You may not use, modify
    or distribute this program under any other version of the
    GNU Affero General Public License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.sf.odinms.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.sf.odinms.client.IItem;
import net.sf.odinms.client.MapleCharacter;
import net.sf.odinms.client.MapleClient;
import net.sf.odinms.client.messages.CommandProcessor;
import net.sf.odinms.net.MaplePacket;
import net.sf.odinms.server.maps.AbstractMapleMapObject;
import net.sf.odinms.server.maps.MapleMapObjectType;
import net.sf.odinms.tools.MaplePacketCreator;

/**
 *
 * @author Matze
 */

public class MapleHiredMerchant extends AbstractMapleMapObject {
    private MapleCharacter owner;
    private List<MapleHiredMerchantItem> items = new ArrayList<MapleHiredMerchantItem>();
    private MapleCharacter slot1 = null;
    private MapleCharacter slot2 = null;
    private MapleCharacter slot3 = null;
    private int FH;
    private String description;
    private boolean opened = false;
    private int ownerid;
    private int mesos;
    private int itemid;

    public MapleHiredMerchant(MapleCharacter owner, String description, int item) {
        this.owner = owner;
        this.description = description;
        this.itemid = item;
    }

    public boolean hasFreeSlot() {
        return (slot1 == null || slot2 == null || slot3 == null);
    }

    public boolean isOwner(MapleCharacter chr) {
        return (ownerid == chr.getId());
    }

    public void addVisitor(MapleCharacter visitor) {
        for (int i = 1; i < 4; i++) {
            if (getSlot(i) == null) {
                setSlot(i, visitor);
                broadcast(MaplePacketCreator.getPlayerShopNewVisitor(visitor, i));
                return;
            }
        }
    }

    public void removeVisitor(MapleCharacter chr) {
        for (int i = 1; i < 4; i++) {
            if (getSlot(i) == chr) {
                setSlot(i, null);
                broadcast(MaplePacketCreator.getPlayerShopRemoveVisitor(i));
                if (getTotalVisitors() == 2) {
                    chr.getMap().broadcastMessage(MaplePacketCreator.addCharBox(getOwner(), 4));
                }
                return;
            }
        }
    }

    public void removeVisitorFromSlot(int slot) {
        removeVisitor(getSlot(slot));
    }

    public MapleCharacter getPlayerFromSlot(int slot) {
        return getSlot(slot);
    }

    public boolean isVisitor(MapleCharacter visitor) {
        return (getSlot(1) == visitor || getSlot(2) == visitor || getSlot(3) == visitor);
    }

    public void addItem(MapleHiredMerchantItem item) {
        items.add(item);
    }

    public void removeItem(int item) {
        items.remove(item);
    }

    /**
     * no warnings for now o.op
     * @param c
     * @param item
     * @param quantity
     */
    public void buy(MapleClient c, int item, short quantity) {
        if (isVisitor(c.getPlayer())) {
            MapleHiredMerchantItem pItem = items.get(item);
            if (items.get(item).getBundles() > 0 && items.get(item).getBundles() < 200) {
                if (c.getPlayer().getMeso() >= pItem.getPrice()) {
                    owner = this.getOwner();
                    synchronized (c.getPlayer()) {
                        int price = pItem.getPrice();
                        IItem newItem = pItem.getItem().copy();
                        pItem.setBundles((short) (pItem.getBundles() - quantity));
                        newItem.setQuantity((short) (newItem.getQuantity() * quantity));
                        c.getPlayer().gainMeso(-price * quantity, true);
                        MapleInventoryManipulator.addFromDrop(c, newItem, "");
                        broadcast(MaplePacketCreator.getHiredMerchantItemUpdate(this));
                        addMesos(price * quantity);
                    }
                }
            }
        }
    }

    public void addMesos(int ammount) {
        this.mesos += ammount;
    }

    public int getMesos() {
        return mesos;
    }

    public int getItemQuantity(int item) {
        MapleHiredMerchantItem it = items.get(item);
        return it.getItem().getQuantity();
    }

    public void broadcastToVisitors(MaplePacket packet) {
        for (int i = 1; i < 4; i++) {
            if (getSlot(i) != null)
                getSlot(i).getClient().getSession().write(packet);
        }
    }

    public int getTotalVisitors() {
        int a = 0;
        for (int i = 1; i < 4; i++) {
            if (getSlot(i) != null) a++;
        }
        return a;
    }

    public void removeVisitors() {
        for (int i = 1; i < 4; i++) {
            if (getSlot(i) != null)
                getSlot(i).changeMap(getSlot(i).getMap(), getSlot(i).getMap().findClosestSpawnpoint(getSlot(i).getPosition()));
        }
    }

    public void broadcast(MaplePacket packet) {
        if (owner.getClient() != null && owner.getClient().getSession() != null)
            owner.getClient().getSession().write(packet);
            broadcastToVisitors(packet);
    }

    public void chat(MapleClient c, String chat) {
        if (!CommandProcessor.getInstance().processCommand(c, chat)) {
            broadcast(MaplePacketCreator.getPlayerShopChat2(c.getPlayer(), chat));
        }
    }

    public void sendShop(MapleClient c) {
        c.getSession().write(MaplePacketCreator.joinHiredMerchant(c, this, (c.getPlayer().getSlot() == 0)));
    }

    public MapleCharacter getOwner() {
        return owner;
    }

    public MapleCharacter getSlot(int slot) {
        switch (slot) {
            case 1:
                return slot1;
            case 2:
                return slot2;
            case 3:
                return slot3;
            default:
                return null;
        }
    }

    public void setSlot(int slot, MapleCharacter person) {
        switch (slot) {
            case 1:
                slot1 = person;
                break;
            case 2:
                slot2 = person;
                break;
            case 3:
                slot3 = person;
                break;
        }
        if (person != null)
            person.setSlot(slot);
    }

    public List<MapleHiredMerchantItem> getItems() {
        return Collections.unmodifiableList(items);
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getItemId() {
        return itemid;
    }

    public void setItemId(int item) {
        this.itemid = item;
    }

    public void open() {
        this.opened = true;
    }

    public void close() {
        this.opened = false;
    }

    public boolean isOpen() {
        return opened;
    }

    public void setOwnerId(int id) {
        this.ownerid = id;
    }

    public int getOwnerId() {
        return ownerid;
    }

    public void setFH(int fh) {
        this.FH = fh;
    }

    public int getFH() {
        return FH;
    }

    @Override
    public void sendDestroyData(MapleClient client) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void sendSpawnData(MapleClient client) {
        throw new UnsupportedOperationException();
    }

    @Override
    public MapleMapObjectType getType() {
        return MapleMapObjectType.SHOP;
    }
}